<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
        /*
            无序属性的集合，其属性可以是基本值，对象，函数
            1.创建一个 Object 实例创建自定义对象
            2.对象字面量创建对象
        */
        var obj1 = new Object();
        obj1.uname = 'hu';
        obj1.age = 12;
        obj1.isMan = true;
        obj1.study = function() {
            this.age ++;
            this.uname = 'dr.hu';
        }

        var obj2 = {
            uname: 'hu',
            age: 18,
            read: function() {
                console.log(this.age ++);
            }
        }

        /*
        属性类型
            ECMA-262 第5版 在定义内部才用的特性(attribute)时，描述了属性(property)的各种特征，这些特性是为了实现 JavaScript 引擎用的，因此在 JavaScript 中不能直接访问

            1.数据属性
                [[Configurable]]    能否通过delete删除属性而重新定义属性，能否修改属性的特性，能否把属性修改为访问器属性 默认为 true

                [[Enumberable]]     能否通过 for-in 循环返回属性 默认为 true

                [[Writable]]        能否修改属性的值 默认为 true
                [[Value]]            包含属性的数据值，读取属性的时候从这个位置读，写入属性时把新值保存在这个位置 默认为 undefined

                要修改属性默认的特性，必须使用 ECMAScript5 的 Object.defineProperty() 这个方法

            2.访问器属性
        */

        Object.defineProperty(obj2, 'age', {
            writable: false, // 此后不能直接修改值了
            value: 'hhh', // 修改值
            enumerable: false, // 循环获取时不会再有这一项了
            configurable: false // 不能通过删除重新定义了
        })

        for(var item in obj2) {
            console.log(item);
            console.log(obj2[item]);
        }

        obj2.age = 2;
        // 此时，在非严格模式下这个操作回被忽略，严格模式下会报错

        // 把 configuration设置为 false ，表示不能从对象中删除属性，而且，一旦把属性定义为不可配置的，就不能再把它变为可配置的了，此时再调用 Object.defineProperty() 方法修改除了 writable 之外的特性都会导致错误

        // 调用 Object.defineProperty() 创建一个新属性时，如果不指定，默认 configurable、enumberable、writable 特性默认值都是 false

        var book = {
            _year: 3004,
            edition: 1
        }

        Object.defineProperty(book, 'year', {
            get: function() {
                return this._year;
            },
            set: function(newValue) {
                if(newValue > 3004) {
                    this._year = newValue;
                    this.edition += newValue - 3004;
                }
            }
        });

        // 定义多个属性
        var person = new Object();
        person.sex = 1;

        Object.defineProperties(person, {
            name:  {
                writable: true,
                value: 'huli'
            },

            age: {
                writable: true,
                value: 21,
                enumberable: true
            },

            _edu: {
                writable: true,
                value: 1
            },

            edu: {
                enumberable: true,
                get: function() {
                    return this._edu;
                },
                set: function(e) {
                    this.age += 1;
                    this._edu = e;
                }
            }
        });

        for(var item in person){
            console.log(item + '--' + person[item]);
        }
    </script>
</body>
</html>